#ifndef __SMART_POINTER_H__
#define __SMART_POINTER_H__

#include <map>

/*
* CLASS THAT REMEMBERS HOW MANY REFERENCES THERE ARE TO IT AND AUTO_DELETES WHEN THERE ARE NONE
*/

template <typename T>
class SP {

	static std::map<void*, unsigned int> _reference_count;
	T *_value;

public:
	SP() : _value(0x0) {}
	SP(T *val) : _value(val) { ++_reference_count[_value]; }
	SP(const SP<T> &ref) : _value(ref._value) { ++_reference_count[_value]; }

	~SP() {
		if (!_value) return;
		else if (--_reference_count[_value] == 0) {
			delete _value;
			_reference_count.erase(_value);
			_value = 0x0;
		}
	}

	T& operator*() { return *_value; }
	T** operator&() { return &_value; }
	T* operator()() { return _value; }

	T& operator*() const { return *_value; }
	T** operator&() const { return &_value; }
	T* operator()() const { return _value; }

	SP<T>& operator=(const SP<T> &other) {
		++_reference_count[other._value];
		SP::~SP();
		_value = other._value;
		return *this;
	}
	SP<T>& operator=(T *other) {
		++_reference_count[other];
		SP::~SP();
		_value = other;
		return *this;
	}
};

template<typename T>
std::map<void*, unsigned int> SP<T>::_reference_count = std::map<void*, unsigned int>();

#endif